import type { IPost, ISectionDetails } from '@/interfaces';
import Link from 'next/link';
import classNames from 'classnames';
import { useContext, useEffect, useState } from 'react';
import Nodata from '@/app/[locale]/common/nodata/nodata';
import ContentHtml from '@/app/[locale]/common/content/html';
import { SectionIdPageContext } from '@/contexts/section-id';
import PostItem from '@/app/[locale]/common/post/item';
import useToast from '@/hooks/useToast';
import { useInfiniteQuery } from '@tanstack/react-query';
import { clientQuerySectionDetailsById } from '@/services/api';
import { toRelativeTime } from '@/lib/tool';
import Spinner from '@/app/[locale]/component/spinner/spinner';

export default function SectionIdH5Page() {
  const { source, translatedFields } = useContext(SectionIdPageContext)!;
  const { show } = useToast();
  const [pages, setPages] = useState<IPost[]>(
    source.sectionDetails.data!.content,
  );

  const clientQuerySectionDetailsByIdQuery = useInfiniteQuery(
    [
      '/forum',
      '/sections',
      '/client',
      source.sectionDetails.basic.id,
      '/details',
      'infinite',
    ],
    async (context) => {
      return (await clientQuerySectionDetailsById({
        id: context.queryKey[3],
        query: context.pageParam,
      })) as ISectionDetails;
    },
    {
      keepPreviousData: true,
      getPreviousPageParam: (firstPage) => {
        if (!firstPage.data!.pageable.previous) {
          return;
        }
        return {
          page: Math.max(firstPage.data!.pageable.page - 1, 0),
        };
      },
      getNextPageParam: (lastPage) => {
        if (!lastPage.data!.pageable.next) {
          return;
        }
        return {
          page: Math.min(
            lastPage.data!.pageable.page + 1,
            lastPage.data!.pageable.pages,
          ),
        };
      },
      initialData: () => {
        return {
          pages: [source.sectionDetails],
          pageParams: [{ page: 0 }],
        };
      },
    },
  );

  useEffect(() => {
    if (clientQuerySectionDetailsByIdQuery.data) {
      setPages(
        clientQuerySectionDetailsByIdQuery.data.pages
          .flatMap((item) => item.data!.content)
          .map((item) => {
            item._contentUpdatedOnText = toRelativeTime(item.contentUpdatedOn);
            return item;
          }),
      );
    }
  }, [clientQuerySectionDetailsByIdQuery.data]);

  async function onClickLoadMore() {
    try {
      await clientQuerySectionDetailsByIdQuery.fetchNextPage();
    } catch (e) {
      show({
        type: 'DANGER',
        message: e,
      });
    }
  }

  return (
    <div className="card rounded-5 border-0">
      <div className="card-body">
        <div className="vstack gap-4">
          <Top />
          <TagGroups />
          <Tags />

          {pages.length > 0 && (
            <>
              <Posts pages={pages} />

              <LoadMoreBtn
                isLoading={clientQuerySectionDetailsByIdQuery.isLoading}
                onClickLoadMore={onClickLoadMore}
              />
            </>
          )}

          {pages.length === 0 && <Nodata />}
        </div>
      </div>
    </div>
  );
}

const Top = () => {
  const {
    source: { sectionDetails },
    translatedFields,
  } = useContext(SectionIdPageContext)!;
  const name = sectionDetails.basic.name;
  const content = sectionDetails.content;
  const admins = sectionDetails.admins;

  return (
    <div className="vstack gap-4">
      <div className="vstack gap-2">
        <h1 className="fs-4 card-title d-flex align-items-center" title={name}>
          <span>{name}</span>
        </h1>

        <div className="card-subtitle d-flex flex-nowrap text-nowrap overflow-x-auto pb-2">
          {admins.map((item, index) => {
            return (
              <div key={item.id} className="p-1">
                <Link
                  href={`/users/${item.id}`}
                  className="link-body-emphasis link-offset-3 link-underline-opacity-0 link-underline-opacity-100-hover"
                >
                  {item.alias}
                </Link>
                {index !== admins.length - 1 && '、'}
              </div>
            );
          })}
        </div>
      </div>

      <ContentHtml content={content} />
    </div>
  );
};

const TagGroups = () => {
  const {
    source: {
      sectionDetails,
      queryParams: { tagId, tagGroupId },
    },
    translatedFields,
  } = useContext(SectionIdPageContext)!;
  const id = sectionDetails.basic.id;
  const tagGroups = sectionDetails.tagGroups ?? [];

  return (
    <>
      {tagGroups.length > 0 && (
        <>
          {tagGroups.map((tagGroupItem) => {
            return (
              <div key={tagGroupItem.id} className="hstack gap-3 mb-3">
                <Link
                  href={`/sections/${id}`}
                  className="badge fw-normal fs-6 link-body-emphasis link-offset-3 link-underline-opacity-0 link-underline-opacity-100-hover"
                >
                  {tagGroupItem.name}
                </Link>

                {(tagGroupItem.tags || []).map((tagItem) => {
                  return (
                    <Link
                      key={tagItem.id}
                      href={`/sections/${id}?tagGroupId=${tagGroupItem.id}&tagId=${tagItem.id}`}
                      className={classNames(
                        'badge fw-normal fs-6 link-body-emphasis link-offset-3 link-underline-opacity-0 link-underline-opacity-100-hover',
                        {
                          'bg-secondary text-light':
                            tagGroupId === tagGroupItem.id + '' &&
                            tagId === tagItem.id + '',
                        },
                      )}
                    >
                      {tagItem.name}
                    </Link>
                  );
                })}
              </div>
            );
          })}
        </>
      )}
    </>
  );
};

const Tags = () => {
  const {
    source: {
      sectionDetails,
      queryParams: { tagId },
    },
    translatedFields,
  } = useContext(SectionIdPageContext)!;
  const id = sectionDetails.basic.id;
  const tags = sectionDetails.tags ?? [];

  return (
    <>
      {tags.length > 0 && (
        <div className="hstack gap-3">
          <Link
            href={`/sections/${id}`}
            className="badge fw-normal fs-6 link-body-emphasis link-offset-3 link-underline-opacity-0 link-underline-opacity-100-hover"
          >
            {translatedFields.all}
          </Link>

          {tags.map((item) => {
            return (
              <Link
                key={item.id}
                href={`/sections/${id}?tagId=${item.id}`}
                className={classNames(
                  'badge fw-normal fs-6 link-body-emphasis link-offset-3 link-underline-opacity-0 link-underline-opacity-100-hover',
                  {
                    'bg-secondary text-light': tagId === item.id + '',
                  },
                )}
              >
                {item.name}
              </Link>
            );
          })}
        </div>
      )}
    </>
  );
};

const Posts = ({ pages }: { pages: IPost[] }) => {
  return (
    <div className="vstack gap-3">
      {pages.map((item, index) => {
        return (
          <div className="row" key={item.id}>
            {index !== 0 && (
              <div className="col-12">
                <div
                  className="yw-bg"
                  style={{ height: '0.35rem', transform: 'scale(1.1)' }}
                ></div>
              </div>
            )}

            <div className="col-12 rounded-3">
              <PostItem item={item} />
            </div>
          </div>
        );
      })}
    </div>
  );
};

const LoadMoreBtn = ({
  onClickLoadMore,
  isLoading,
}: {
  onClickLoadMore: () => void;
  isLoading: boolean;
}) => {
  return (
    <div className="row mt-4 mb-3">
      <div className="col">
        <button
          onClick={onClickLoadMore}
          disabled={isLoading}
          type="button"
          className="btn rounded-pill text-secondary-emphasis w-100"
        >
          {isLoading ? <Spinner /> : <i className="bi bi-three-dots"></i>}
        </button>
      </div>
    </div>
  );
};
